/***************************************************************************
 *   Copyright (C) 2010 by Oleg Goncharov  *
 *   $EMAIL$                           *                          
 *                                                                         *
 *   This file is part of ChessVision.                                     *
 *                                                                         *
 *   ChessVision is free software; you can redistribute it and/or modify   *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include <opencv/cv.h>

#include "cpointbackhist.h"

CPointBackHist::CPointBackHist(const Mat &sample, float min_size_mul, float max_size_mul, int _nsteps) 
{
    size = sample.size();
    nsteps = _nsteps;
    min_mul = min_size_mul;
    mul_step = (max_size_mul - min_size_mul) / nsteps;

    method = CV_COMP_CORREL;
    threshold = 0.0;

    int hsize[] = {30, 32};
    float h_range[] = {1, 180}, s_range[] = {0, 255};
    const float * ranges[] = { h_range, s_range };
    // Hue and Saturation channels
    int channels[] = {0, 1};
    Mat hsv;

    cvtColor(sample, hsv, CV_BGR2HSV);

    calcHist( &hsv, 1, channels, Mat(), hist, 2, hsize, ranges );

    //cvNormalizeHist(hist., 1.0); // TODO check if it needed now

}

CPointBackHist::~CPointBackHist() 
{
}


bool CPointBackHist::DetectPoint(const Mat& img, cv::Point2f& point) //TODO test
{
    Point min_loc;
    double min, max, best = 1e100;
    double mul = min_mul;

    Mat hsv, diff(img.size(), CV_32FC1);
    // Hue and Saturation channels
    int channels[] = {0, 1};
    // hue varies from 0 to 179, see cvtColor
    float hranges[] = { 0, 180 };
    // saturation varies from 0 (black-gray-white) to
    // 255 (pure spectrum color)
    float sranges[] = { 0, 256 };
    const float* ranges[] = { hranges, sranges };
    
    cvtColor( img, hsv, CV_BGR2HSV );


    for (int i = 0; i < nsteps; i++, mul += mul_step) 
    {
        Size cur_size = Size(cvRound(size.width*mul), cvRound(size.height*mul));
        Mat diff_roi = diff(Rect(0,0, img.cols - cur_size.width + 1, img.rows - cur_size.height + 1));
	
	calcBackProject( &hsv, 1, channels, hist, diff_roi, ranges );
        //cvCalcBackProjectPatch(&planes, diff, cur_size, hist, method, 1.0);
	
        minMaxLoc(diff_roi, &min, &max, &min_loc, 0);
        if (min < best)
	{
            best = min;
            point.x = min_loc.x + cur_size.width*0.5;
            point.y = min_loc.y + cur_size.height*0.5;
        }
    }
    
    return !(min > threshold);
}

